use crate::config::app_config::CONFIG;
use crate::entity::{fetch_page, Page, PaginationOptions};
use crate::wechat::entity::wechat_user::{WechatUser, WechatUserPageReq};
use crate::SQLX;
use anyhow::anyhow;
use calamine::{open_workbook, RangeDeserializerBuilder, Reader, Xlsx};
use ormlite::Model;
use salvo::{Depot, Request};
use sqlx::{QueryBuilder, Sqlite};
use std::path::Path;

pub struct WechatUserService {}


impl WechatUserService {
    pub async fn import(request: &mut Request, depot: &mut Depot) -> anyhow::Result<()> {
        let file = request.file("file").await.ok_or(anyhow!("file not found"))?;
        let dest = format!("{}{}/{}", env!("CARGO_MANIFEST_DIR"), &CONFIG.server.file.path, file.name().unwrap());
        std::fs::copy(&file.path(), Path::new(&dest))?;
        let mut workbook: Xlsx<_> = open_workbook(dest)?;
        let range = workbook.worksheet_range("Sheet1")?;
        let mut iter = RangeDeserializerBuilder::with_headers(&["用户id（不填）", "用户昵称", "openId", "头像", "微信号", "分数", "邀请码", "邀请数量", "会员开始时间", "会员结束时间", "会员类型", "创建日期（不填）", "状态（不填）"]).from_range::<_, WechatUser>(&range)?;
        let sqlx = SQLX.get().ok_or(anyhow!("db error"))?;
        let mut db = sqlx.acquire().await?;
        while let Some(Ok(data)) = iter.next() {
            data.insert(&mut db).await?;
        }
        Ok(())
    }

    pub async fn export(request: &mut Request, depot: &mut Depot) -> anyhow::Result<()> {
        Ok(())
    }


    pub async fn cursor(request: &mut Request, depot: &mut Depot) -> anyhow::Result<Vec<WechatUser>> {
        let wechat_user_page_req = request.parse_json::<WechatUserPageReq>().await?;
        let sqlx = SQLX.get().ok_or(anyhow!("db error"))?;
        let mut db = sqlx.acquire().await?;
        let mut wrapper = WechatUser::select();
        if let Some(user_name) = wechat_user_page_req.user_name {
            wrapper = wrapper.where_("user_name like '%?%'").bind(user_name);
        }
        wrapper = wrapper.where_("user_id > ?").bind(wechat_user_page_req.user_id).where_("state =?").bind(1);
        let result: Vec<WechatUser> = wrapper.fetch_all(&mut *db).await?;
        Ok(result)
    }

    pub async fn page(request: &mut Request, depot: &mut Depot) -> anyhow::Result<Page<WechatUser>> {
        let wechat_user_page_req = request.parse_json::<WechatUserPageReq>().await?;
        let mut builder: QueryBuilder<Sqlite> = QueryBuilder::new("select * from wechat_user where 1=1 ");

        if let Some(user_name) = wechat_user_page_req.user_name {
            builder.push(format!(" and user_name like '%{}%' ", user_name));
        }
        let sql = builder.sql();
        let options = PaginationOptions { page_no: wechat_user_page_req.page_no, page_size: wechat_user_page_req.page_size };
        let page: Page<WechatUser> = fetch_page(sql, &options).await?;
        Ok(page)
    }
    pub async fn insert(request: &mut Request, depot: &mut Depot) -> anyhow::Result<()> {
        let wechat_user = request.parse_json::<WechatUser>().await?;
        let sqlx = SQLX.get().ok_or(anyhow!("db error"))?;
        let mut db = sqlx.acquire().await?;
        wechat_user.insert(&mut db).await?;
        Ok(())
    }
}